package com.itheima;

//---/**--一回车文档注释就出来了

//阿里巴巴推崇的代码风格,--->卫语言风格--->判断基本都是取翻  去哪不是做反的

import com.sun.security.jgss.GSSUtil;
import com.sun.source.tree.NewArrayTree;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

//操作类:在开发中,有的叫...service  ;...controller
//ATM系统:账户操作对象,负责账户数据的业务处理
public class ATM {

    //首先需要一个容器,存储账户对象,在开发中是不会这个样的,会直接通过通信传到企业的数数据库中去
    private ArrayList<Account> allAccounts = new ArrayList<>();

    //创建一个扫描器因为后面,肯定是需要的
    private Scanner sc = new Scanner(System.in);
    //成员遍历基本都是要private
    //注意: 定义一个账户类型的变量记住当前ATM系统登录成功的账户对象
    private Account loginAccount;//存的是一个地址,指向堆内存,当前是null

    //开机
    public void start() {
        while (true) {
            //展示界面
            System.out.println("==============欢迎来到黑马ATM银行系统==================");
            System.out.println("请输入您的指令");
            System.out.println("1.用户登录");
            System.out.println("2.用户开户");

            //接受用户输入的指令
            String command = sc.next();//因为String容错率低
            //进入判断语句
            switch (command) {
                case "1":
                    //登录
                    login();
                    break;
                case "2":
                    //开户
                    registerAccount();
                    break;
                default:
                    System.out.println("指令有误,请您重新输入");
            }
        }
    }

    /**
     * 负责用户登录
     */
    private void login() {
        System.out.println("================用户登录==================");
        //首先进行判断,看系统中是否有账号,如果没有就直接提示用户开户
        if (allAccounts.size() == 0) {
            System.out.println("当前系统一个账户都没有,请开户");
            return;
        }//用卫语句风格
        while (true) {
            //1.用户输入卡号,根据卡号取账户集合中查询账户对象
            System.out.println("请输入您的卡号:");
            String CardId = sc.next();

            //这就是写根据卡号查询方法的作用,现在就根据卡号取查询用户名,如果用户名存在就让用户输入密码
            Account acc = getAccountByCardId(CardId);
            if (acc == null) {
                System.out.println("您输入的卡号不存在,请您重新输入");
                continue;
            }
            //如果代码执行到了这里,就证明,账户正确
            //2.请您输入密码
            System.out.println("请您输入密码:");
            String password = sc.next();
            //对密码进行验证
            if (!password.equals(acc.getPassWord())) {
                System.out.println("您输入的密码有误,请重新登陆");
                continue;
            }

            //将登陆成功的账户进行记录,也就是进行解耦合
            loginAccount = acc;
            //3.登录成功,一旦到了这里就登陆成功--->这里要给用户一个称呼,要有先生和女士,所以到对男与女进行封装
            System.out.println("恭喜您," + acc.getUserInfo() + "登录成功,您的卡号:" + acc.getCardId());
            //登成功后就展示操作界面
            showUserCommand();
            return;
        }

    }

    private void showUserCommand() {
        while (true) {
            System.out.println("=================用户登录后的操作页面====================");
            System.out.println("1.查询");
            System.out.println("2.存款");
            System.out.println("3.取款");
            System.out.println("4.转账");
            System.out.println("5.修改密码");
            System.out.println("6.注销");
            System.out.println("7.退出");
            String command = sc.next();
            switch (command) {
                case "1":
                    //查询
                    showMyAccount();
                    break;
                case "2":
                    //存款
                    depositMoney();
                    break;
                case "3":
                    //取款
                    withdrawMoney();
                    break;
                case "4":
                    //转账
                    transferAccounts();
                    break;
                case "5":
                    //修改密码
                    changePassword();
                    return;
                case "6":
                    //注销
                    logOff();
                    return;
                case "7":
                    //退出
                    System.out.println("退出成功,欢迎下次登录,感谢您的支持");
                    return;
                default:
                    System.out.println("指令不存在,请您重新输入");
            }
        }

    }

    //实现注销业务
    private void logOff() {
        //进行询问
        System.out.println("您是否要进行销户,如果是请输入Y/N");
        //接受用户输入的东西
        String command = sc.next();
        if (!command.equalsIgnoreCase("y")){
            return;
        }
        //进行销户
        //判断是否有钱
        if (loginAccount.getMoney() != 0){
            System.out.println("您的账户还存有存款,不能进行销户");
            return;
        }
        //进行销户吧
        allAccounts.remove(loginAccount);
        System.out.println("销户成功");
    }

    //修改密码业务
    private void changePassword() {
        //获取当前用户的密码
        System.out.println("=================修改密码====================");
        while (true) {
            System.out.println("请输入当前账户密码");
            //对密码进行接受
            String password = sc.next();
            //用一个遍历对当前用户的Miami进行存储
            String okPassWord = loginAccount.getPassWord();
            //对密码进行判断
            if (!okPassWord.equals(password)){
                System.out.println("密码错误,请重新输入当前账户的密码");
                continue;
            }
            //到这里就证明,能进行修改
            System.out.println("请您输入新密码:");
            String newPassWord = sc.next();
            System.out.println("请您确认新密码:");
            String okNewPassWord = sc.next();
            //对两次密码进行判断
            if (!newPassWord.equals(okNewPassWord)){
                System.out.println("两次密码的结果不一致,请再次输入当前账户密码");
                continue;
            }
            //修改密码
            loginAccount.setPassWord(okPassWord);
            System.out.println("恭喜您,修改密码成功,请您重新输入指令登录");
            return;
        }
    }

    //进行转账业务的处理(独立功能独立成一个方法)
    private void transferAccounts() {
        //首先进行判断是否有其他账户,如果只有一个账户,就无法进行转账
        if (allAccounts.size() <= 1){
            System.out.println("当前系统只有一个用户,不能进行转账操作,请按7回到主界面,进行开户");
            return;//直接返回到上一层
        }
        //判断自己户头是否有钱
        if (loginAccount.getMoney() == 0){
            System.out.println("余额不足,不能进行转账");
            return;
        }
        //展示当前是什么业务
        System.out.println("=============转账业务=================");
        //意识用户输入要转账的用户卡号
        System.out.println("请输入您要输入用户的卡号:");
        String CardId = sc.next();
        //判断卡号是否存在,这就要使用到根据卡号查询用户
        Account acc = getAccountByCardId(CardId);
        if (acc == null){
            System.out.println("当前卡号不存在,请重新输入指令");
            return;
        }
        //到这里就证明可以进行转账
        //提示进行输入对方的姓氏
        System.out.println("您新输入转账用户的姓氏");
        System.out.println("转账账户的姓名如下:" +
                acc.getUserName().replace(acc.getUserName().charAt(0) + "", "*"));
        String name = sc.next();
        //验证输入的姓氏是否正确
        if (!name.equals(acc.getUserName().charAt(0) + "")){
            System.out.println("您输入的姓氏,不正确");
            return;//不让他输入了
        }

        //到这里就证明正确了
        //进行转账业务
        //首先提示用户输入转账金额
        while (true) {
            System.out.println("请输入您的转账金额:");
            double money = sc.nextDouble();
            //对金额跟余额进行比较
            if (money < loginAccount.getMoney()){
                System.out.println("你的余额不足:" + money + "请重新输入");
                continue;
            }
            //这里就可以进行修改金额了
            acc.setMoney(acc.getMoney() + money);
            loginAccount.setMoney(loginAccount.getMoney() - money);
            return;//直接结束方法
        }

    }

    //进行取款业务
    private void withdrawMoney() {
        System.out.println("==========取款业务==============");

        //取款要求:1.先判断账户余额是否大于 >= 100元 如果够, 让用户取框金额
        //2.需要判断取款金额是否超过当前限额,以及余额是否足够
        //首先获取当前用户已有的金额
        double money = loginAccount.getMoney();
        //用卫语句代码
        if (money < 100){
            System.out.println("亲,您余额不足一百元,不能执行取款业务,您还可以进行其他操作");
            return;
        }
        while (true) {
            //到这里证明满足了,第一个条件,提示用户
            System.out.println("请输入您的取款金额");
            double getMoney = sc.nextDouble();

            //获取每次的取款限额
            double limit = loginAccount.getLimit();
            //进行限额与余额跟取款金额进行比较
            if (money > limit){
                System.out.println("取款超出限额,请重新输入取款金额,注意每次限额" + limit);
                continue;
            }
            //对取款金额,与余额进行比较,如果余额小就显示余额不足,不能取款
            if (getMoney > money){
                System.out.println("余额不足" + getMoney +"不能完成取款,请您重新输入取款金额");
                continue;
            }
            //代码能够执行到这里证明能进行合理的取款
            System.out.println("恭喜您,取款成功,请妥善保管好,您的钱");
            loginAccount.setMoney(money - getMoney);
            return;

        }

       /* if (money >= 100) {

            //进行第二步判断
            //对金额进行修改
            loginAccount.setMoney(money - getMoney);
        } else {
            System.out.println("余额不足,不能进行取款业务");
            return;
        }*/
    }

    //进行取款任务
    private void depositMoney() {
        System.out.println("==========存款业务==============");
        System.out.println("请输入您的存款金额");
        double AddMoney = sc.nextDouble();
        //修改当前用户的存款,为他加上修改后的前
        loginAccount.setMoney(loginAccount.getMoney() + AddMoney);
        //展示余额,提示账户村矿成功
        System.out.println("恭喜您," + loginAccount.getUserInfo() + "存款成功");
        System.out.println("您的余额是:" + loginAccount.getMoney());

    }

/*    //这只是对账户的金额进行修改
    private void setMoney(double setmoney) {
     *//*   //提示是什么功能
        System.out.println("================取款与存款操作==============");
        System.out.println("1.取款");
        System.out.println("2.存款");
        //进switch判断
        String command = sc.next();
        switch(command){
            case "1":

        }*//*
        //首先获取当前用户
//        System.out.println("===========");
        double money = loginAccount.getMoney();
        loginAccount.setMoney(money + setmoney);
    }*/

    /**
     * 查询:展示当前登录成功改的用户信息,注意不能展示密码
     */
    private void showMyAccount() {
        //1.首先要获取当前登录成功的用户对象,因为数据封装在对象中-->如果将一个对象进行到处乱传,就会导致过于耦合,如果一个功能修改,就会造成,牵一发而动全身
        //所以要定义一个全局变量记录当前用户
        System.out.println(loginAccount.getUserInfo() + "您的信息如下:");
        System.out.println("卡号:" + loginAccount.getCardId());
        System.out.println("姓名" + loginAccount.getUserName());
        System.out.println("余额:" + loginAccount.getMoney());
        System.out.println("每次取现额度:" + loginAccount.getLimit());
    }

    //开户的方法,只能是银行为你开户,所以,私有也没问题
    //逻辑就是:每一个户头就是一个对象,要将数据封装到对象中去,进行存储集合里面,大多数内容都是用户进行输入
    private void registerAccount() {
        System.out.println("================用户开户===================");
        //1.创建用户对象
        Account acc = new Account();
        //2.封装数据
        //提示用户进行输入
        System.out.println("请您输入账号名:");
        String userName = sc.next();
        //添加到对象中
        acc.setUserName(userName);
        while (true) {
            System.out.println("请您输入您的性别:");
            String sex = sc.next();//"男" || "女"
            if (sex.equals("男") || sex.equals("女")) {
                //检验性别合理,进行封装到对象中去
                acc.setSex(sex.charAt(0));//注意性别是char
                break;
            } else {
                System.out.println("您输入的性别是不合理的,请重新输入");
            }
        }

        //密码
        while (true) {
            System.out.println("请您设置您的密码:");
            String password = sc.next();
//            System.out.println("请您再次输入您的密码");
            System.out.println("请您再次确认密码");
            String okPassWord = sc.next();
            //对两次密码进行验证
            if (password.equals(okPassWord)) {
                //密码正确进行封装
                acc.setPassWord(okPassWord);
                break;
            } else {
                System.out.println("您两次输入的密码不一致,请重新输入");
            }
        }

        //每日限额
        //提示用户
        while (true) {
            System.out.println("请你输入每次取款的额度: ");
            double limit = sc.nextDouble();
            //对限额进行判断
            if (limit >= 1000) {
                //合理就封装到对象中去
                acc.setLimit(limit);
                break;
            } else {
                System.out.println("每次取款限额必须大于等于1000元,请重新输入");
            }
        }

        //进行卡号的生成-->生成一个8为的卡号
        //创建随机数对象
        //定义变量用于拼接卡号
        while (true) {
            String CardId = "";
            Random random = new Random();
            for (int i = 0; i < 8; i++) {
                //随机产生0-9之间的数字
                CardId += random.nextInt(10);
            }
            //需求:要进行卡号的唯一性进行比较,判断卡号是否存在,如果存在,进行重新生成(独立功能,独立成方法)
            //判断卡号是否存在,如果不存在就作为新卡号,否则不能作为新卡号(独立功能)
            //由于后面基本都会用到根据一个卡号查询账户
            Account otherAccount = getAccountByCardId(CardId);//为了后面进行铺垫,其实还有很多判断的方法
            //对用户进行判断,看是否存在相同的卡号
            if (otherAccount == null) {
                //证明卡号是不存咋的,进行封装
                acc.setCardId(CardId);
                break;
            }
        }


        //3.将封装了数据的对象添加到集合中去
        allAccounts.add(acc);
        //成功后的提示
        System.out.println("恭喜您, 开户成功,您的卡号是: " + acc.getCardId() + ", 请妥善保管");
    }

    /**
     * 根据卡号去查询账户------>注意没有账户是一个对象
     *
     * @param CardId
     * @return
     */
    public Account getAccountByCardId(String CardId) {
        //遍历集合获取所有对象,进行比较
        for (int i = 0; i < allAccounts.size(); i++) {
            //获取每个对象
            Account account = allAccounts.get(i);
            //对每个对象的卡号进行比较
            if (account.getCardId().equals(CardId)) {
                return account;
            }
        }
        //如果没有卡号不存在,证明账号不存在
        return null;
    }

}
